package top.codef.secure.handlers;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CsrfToken;

import com.fasterxml.jackson.databind.ObjectMapper;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.codef.secure.config.interfaces.LoginSuccessDecorator;
import top.codef.secure.pojomodel.SecureResponseEnum;
import top.codef.secure.properties.CerberusCsrfProperties;
import top.codef.secure.properties.CerberusLoginReturnProperties;

public class CerberusLoginSuccessHandler implements AuthenticationSuccessHandler {

	private final ObjectMapper objectMapper;

	@SuppressWarnings("deprecation")
	private final static String defaultContentType = MediaType.APPLICATION_JSON_UTF8_VALUE;

	private final Log logger = LogFactory.getLog(CerberusLoginSuccessHandler.class);

	private final CerberusCsrfProperties cerberusCsrfProperties;

	private final CerberusLoginReturnProperties cerberusLoginReturnProperties;

	private final LoginSuccessDecorator loginSuccessDecorator;

	public CerberusLoginSuccessHandler(ObjectMapper objectMapper, CerberusCsrfProperties cerberusCsrfProperties,
			CerberusLoginReturnProperties cerberusLoginReturnProperties) {
		this.objectMapper = objectMapper;
		this.cerberusCsrfProperties = cerberusCsrfProperties;
		this.cerberusLoginReturnProperties = cerberusLoginReturnProperties;
		this.loginSuccessDecorator = (request, response, authentication) -> {
			logger.debug("login success：" + authentication.getPrincipal());
			return null;
		};
	}

	public CerberusLoginSuccessHandler(ObjectMapper objectMapper, CerberusCsrfProperties cerberusCsrfProperties,
			CerberusLoginReturnProperties cerberusLoginReturnProperties, LoginSuccessDecorator loginSuccessDecorator) {
		this.objectMapper = objectMapper;
		this.cerberusCsrfProperties = cerberusCsrfProperties;
		this.cerberusLoginReturnProperties = cerberusLoginReturnProperties;
		this.loginSuccessDecorator = loginSuccessDecorator;
	}

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		var result = loginSuccessDecorator.decorate(request, response, authentication);
		if (cerberusCsrfProperties != null) {
			CsrfToken csrfToken = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
			if (csrfToken != null)
				response.setHeader(cerberusCsrfProperties.getCsrfHeaderName(), csrfToken.getToken());
		}
		response.setContentType(defaultContentType);
		response.getWriter()
				.write(objectMapper.writeValueAsString(SecureResponseEnum.LOGIN_SUCCESS.createSecureModel(
						cerberusLoginReturnProperties.getSuccessMessageStatus(),
						cerberusLoginReturnProperties.getSuccessMessage(), result)));
	}

}
